home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / spiele / think / chinachallenge3 / c++ / cc3.cc < prev    next >
C/C++ Source or Header  |  1995-11-02  |  11KB  |  517 lines

  1. //
  2. // China Challenge III - the C++ Version
  3. //
  4. // author    : Gunther Nikl
  5. // created    : 9-may-94
  6. // last change    : 2-nov-95
  7. //
  8.  
  9. //
  10. // our include
  11. //
  12.  
  13. #include "cc3.h"
  14.  
  15. //
  16. // implementation
  17. //
  18.  
  19. China::China()
  20. {
  21. }
  22.  
  23. // init functions
  24.  
  25. LONG China::Init()
  26. {
  27.   LONG retval;
  28.  
  29.   if ((retval=MakeGfx()))
  30.     InitMusic();
  31.   return retval;
  32. }
  33.  
  34. LONG China::MakeGfx()
  35. {
  36.   PLANEPTR *planes;
  37.   int i;
  38.  
  39.   if ((ScrPtr=OpenScreen(&NewScreen)))
  40.   {
  41.     NewWindow.Screen=ScrPtr;
  42.     if ((WinPtr=OpenWindow(&NewWindow)))
  43.     {
  44.       SetMenuStrip(WinPtr,&MenuStrip[0]);
  45.       ShowTitle(ScrPtr,FALSE);
  46.       LoadRGB4(&ScrPtr->ViewPort,&ColorTab[0],1<<DEPTH);
  47.       InitRastPort(&RastPort);
  48.       SetFont(&RastPort,WinPtr->IFont);
  49.       InitBitMap(&BitMap,DEPTH,WIDTH,HEIGHT);
  50.       for (planes=&BitMap.Planes[0],i=DEPTH; i!=0 ; --i)
  51.        {
  52.          if (!(*planes++=AllocRaster(WIDTH,HEIGHT))) return;
  53.        }
  54.       RastPort.BitMap=&BitMap;
  55.       CurrentTime((ULONG *)&EntryTable[0],(ULONG *)&RandVal);
  56.       MakeDragon();
  57.       ScreenToFront(ScrPtr);
  58.       return 1;
  59.     }
  60.   }
  61.   /* return 0; */
  62. }
  63.  
  64. VOID China::InitMusic()
  65. {
  66.   ULONG rlen;
  67.   BPTR file;
  68.  
  69.   AudioPort.mp_Node.ln_Type=NT_MSGPORT;
  70.   if ((BYTE)(AudioPort.mp_SigBit=AllocSignal(-1L))>=0)
  71.   {
  72.     AudioPort.mp_SigTask=FindTask(NULL);
  73.     NEWLIST(&AudioPort.mp_MsgList);
  74.  
  75.     AudioIO.ioa_Request.io_Message.mn_Node.ln_Type=NT_MESSAGE;
  76.     AudioIO.ioa_Request.io_Message.mn_Node.ln_Pri=ADALLOC_MAXPREC;
  77.     AudioIO.ioa_Request.io_Message.mn_ReplyPort=&AudioPort;
  78.     AudioIO.ioa_Request.io_Flags=ADIOF_NOWAIT;
  79.     AudioIO.ioa_Data=ChannelMap;
  80.     AudioIO.ioa_Length=sizeof(ChannelMap);
  81.     if (!OpenDevice(AudioName,0,&AudioIO.ioa_Request,0))
  82.     {
  83.       AudioOpen++;
  84.       if ((SampleBuf=AllocMem(SAMPLESIZE,MEMF_CHIP|MEMF_PUBLIC)))
  85.       {
  86.         if ((file=Open((STRPTR)SampleName,MODE_OLDFILE)))
  87.         {
  88.           rlen=Read(file,SampleBuf,SAMPLESIZE);
  89.           Close(file);
  90.           if (rlen==SAMPLESIZE)
  91.           {
  92.             if (!(ciaa.ciapra & CIAF_LED))
  93.             {
  94.               ciaa.ciapra |= CIAF_LED; AudioOpen++;
  95.             }
  96.             OptMusic();
  97.             if (!AudioIO.ioa_Request.io_Error)
  98.               return;
  99.           }
  100.         }
  101.       }
  102.       FreeMusic();
  103.     }
  104.   }
  105.   MenuItems[7].Flags &= ~(CHECKED|ITEMENABLED|CHECKIT);
  106. }
  107.  
  108. // cleanup functions
  109.  
  110. VOID China::FreeMusic()
  111. {
  112.   if (AudioOpen)
  113.     CloseDevice(&AudioIO.ioa_Request);
  114.   if ((BYTE)AudioPort.mp_SigBit>0)
  115.   {
  116.     FreeSignal(AudioPort.mp_SigBit); AudioPort.mp_SigBit=0;
  117.   }
  118.   if (SampleBuf)
  119.   {
  120.     FreeMem(SampleBuf,SAMPLESIZE); SampleBuf=NULL;
  121.     if (--AudioOpen)
  122.       ciaa.ciapra &= ~CIAF_LED;
  123.     AudioOpen=0;
  124.   }
  125. }
  126.  
  127. VOID China::CloseGfx()
  128. {
  129.   PLANEPTR *planes,p;
  130.   int i;
  131.  
  132.   for (planes=&BitMap.Planes[0],i=DEPTH; i!=0 ; i--)
  133.    {
  134.      if ((p=*planes++))
  135.        FreeRaster(p,WIDTH,HEIGHT);
  136.    }
  137.   if (WinPtr)
  138.   {
  139.     ClearMenuStrip(WinPtr); CloseWindow(WinPtr);
  140.   }
  141.   if (ScrPtr)
  142.     CloseScreen(ScrPtr);
  143. }
  144.  
  145. // main loop
  146.  
  147. VOID China::Game()
  148. {
  149.   volatile struct IntuiMessage *imsg;
  150.   ULONG imClass;
  151.   UWORD imCode;
  152.  
  153.   for (;;)
  154.    {
  155.      if (!(imsg=(struct IntuiMessage *)GetMsg(WinPtr->UserPort)))
  156.        WaitPort(WinPtr->UserPort);
  157.      else
  158.      {
  159.        imClass = imsg->Class; imCode  = imsg->Code;
  160.        ReplyMsg((struct Message *)imsg);
  161.        DoIDCMP(imClass,imCode);
  162.        if (EndAll)
  163.          break;
  164.      }
  165.    }
  166. }
  167.  
  168. // process all messages
  169.  
  170. VOID China::DoIDCMP(ULONG imClass, ULONG imCode)
  171. {
  172.   LONG index,pos;
  173.  
  174.   if (imClass == MENUPICK)
  175.   {
  176.     ShowTitle(ScrPtr,FALSE);
  177.     for (;;)
  178.      {
  179.        SetAPen(&ScrPtr->RastPort,4);
  180.        Move(&ScrPtr->RastPort,0,0);
  181.        Draw(&ScrPtr->RastPort,WIDTH-1,0);
  182.        if ((UWORD)imCode == MENUNULL)
  183.          break;
  184.        switch (MENUNUM(imCode))
  185.        {
  186.          case 0: switch (ITEMNUM(imCode))
  187.                  {
  188.                    case 0: ProjectAbout(); break;
  189.                    case 1: EndAll=~0; break;
  190.                  }
  191.                  break;
  192.  
  193.          case 1: switch (ITEMNUM(imCode))
  194.                  {
  195.                    case 0: MakeDragon(); break;
  196.                    case 1: OptUndoMove(); break;
  197.                    case 2: OptUndoAll(); break;
  198.                    case 3: OptLoadDragon(); break;
  199.                    case 4: OptSaveDragon(); break;
  200.                    case 5: OptMusic(); break;
  201.                  }
  202.                  break;
  203.        }
  204.        imCode=(ULONG)(ItemAddress(&MenuStrip[0],imCode))->NextSelect;
  205.        if (EndAll)
  206.          break;
  207.      }
  208.   }
  209.   else
  210.     if ((imClass==MOUSEBUTTONS) && (imCode==IECODE_LBUTTON) && (pos=CheckPos())>=0)
  211.     {
  212.       if (TwoSelected && (PiecePos2 == pos || PiecePos1 == pos))
  213.       {
  214.         index=(MAXCOUNT-PieceCount)/2; PieceCount-=2;
  215.         NewDragon.PieceTable[PiecePos1] |= 0x80; NewDragon.UndoTable[index].pos1 = PiecePos1;
  216.         NewDragon.PieceTable[PiecePos2] |= 0x80; NewDragon.UndoTable[index].pos2 = PiecePos2;
  217.         ShowDragon();
  218.       }
  219.       else
  220.       {
  221.         if (OnePiece)
  222.         {
  223.           if (PiecePos1==pos)
  224.             return;
  225.           if (NewDragon.PieceTable[PiecePos1]==NewDragon.PieceTable[pos])
  226.           {
  227.             TwoSelected=1; PiecePos2=pos;
  228.           }
  229.           else
  230.           {
  231.             OnePiece=1; PiecePos1=pos;
  232.           }
  233.         }
  234.         else
  235.         {
  236.           OnePiece=1; PiecePos1=pos;
  237.         }
  238.         DrawImage(WinPtr->RPort,&Images[NewDragon.PieceTable[pos]],(TwoSelected ? 291:3),85);
  239.       }
  240.     }
  241. }
  242.  
  243. // project function(s)
  244.  
  245. VOID China::ProjectAbout()
  246. {
  247.   struct Window *wptr;
  248.   struct RastPort *rp;
  249.   struct About *p;
  250.   int i,j;
  251.  
  252.   AboutWindow.Screen=ScrPtr;
  253.   if ((wptr=OpenWindow(&AboutWindow)))
  254.   {
  255.     rp=wptr->RPort;
  256.     SetRast(rp,5); SetBPen(rp,5);
  257.     for (i=2; i!=0; i--)
  258.      { for (p=&About1[0],j=9; j!=0; p++,j--)
  259.         {
  260.           SetAPen(rp,p->pens[i-1]); Move(rp,p->x+i-1,p->y+i-1); Text(rp,(STRPTR)&p->text[0],23);
  261.         }
  262.        SetDrMd(rp,JAM1);
  263.      }
  264.     for (i=2; i!=0; i--)
  265.       DrawImage(rp,&Images[Random(30)+1],(i==2 ? 2:168),23);
  266.     WaitPort(wptr->UserPort);
  267.     CloseWindow(wptr);
  268.   }
  269. }
  270.  
  271. // option functions
  272.  
  273. VOID China::OptUndoMove()
  274. {
  275.   LONG index;
  276.  
  277.   if ((index=(MAXCOUNT-PieceCount)/2-1)>=0)
  278.   {
  279.     PieceCount+=2;
  280.     NewDragon.PieceTable[NewDragon.UndoTable[index].pos1] &= 0x7f;
  281.     NewDragon.PieceTable[NewDragon.UndoTable[index].pos2] &= 0x7f;
  282.     ShowDragon();
  283.   }
  284. }
  285.  
  286. VOID China::OptUndoAll()
  287. {
  288.   BYTE *p;
  289.   short i;
  290.  
  291.   if (PieceCount!=MAXCOUNT)
  292.   {
  293.     PieceCount=MAXCOUNT;
  294.     for (p=&NewDragon.PieceTable[0],i=288; i!=0; *p++ &= 0x7f,i--) ;
  295.     ShowDragon();
  296.   }
  297. }
  298.  
  299. VOID China::OptLoadDragon()
  300. {
  301.   WORD header[2];
  302.   BPTR file;
  303.  
  304.   if ((file=ReqFile(0)))
  305.   {
  306.     Read(file,(APTR)&header[0],sizeof(header));
  307.     if (header[0]==0x4333)
  308.     {
  309.       PieceCount=header[1];
  310.       Read(file,&NewDragon,sizeof(struct Dragon));
  311.       ShowDragon();
  312.     }
  313.     Close(file);
  314.   }
  315. }
  316.  
  317. VOID China::OptSaveDragon()
  318. {
  319.   WORD header[2];
  320.   BPTR file;
  321.  
  322.   if ((file=ReqFile(1)))
  323.   {
  324.     header[0]=0x4333; header[1]=PieceCount;
  325.     Write(file,(APTR)&header[0],sizeof(header));
  326.     Write(file,&NewDragon,sizeof(struct Dragon));
  327.     Close(file);
  328.   }
  329. }
  330.  
  331. VOID China::OptMusic()
  332. {
  333.   struct IOAudio *areq;
  334.    BYTE OnOff;
  335.   UWORD cmd;
  336.  
  337.   if (AudioOpen)
  338.   {
  339.     OnOff=(MenuItems[7].Flags&CHECKED?~0:0);
  340.     if (Music!=OnOff)
  341.     {
  342.       areq=&AudioIO;
  343.       cmd=ADCMD_FINISH;
  344.       if (OnOff)
  345.       {
  346.         areq->ioa_Request.io_Flags=IOF_QUICK|ADIOF_PERVOL;
  347.         areq->ioa_Data=(UBYTE *)SampleBuf+104L;
  348.         areq->ioa_Length=2*51984;
  349.         areq->ioa_Period=428;
  350.         areq->ioa_Volume=55;
  351.         areq->ioa_Cycles=0;
  352.         cmd=CMD_WRITE;
  353.       }
  354.       areq->ioa_Request.io_Command=cmd;
  355.       BeginIO(&areq->ioa_Request);
  356.       Music=~Music;
  357.     }
  358.   }
  359. }
  360.  
  361. // mouseclick valid ?
  362.  
  363. LONG China::CheckPos()
  364. {
  365.   unsigned int x,y,z,d;
  366.   int i;
  367.  
  368.   for (d=1,i=3; i>=0; d+=3,i--)
  369.    {
  370.      if ( ((y=(WinPtr->MouseY-d)/30)<6) && ((x=(WinPtr->MouseX-d)/25)<12)
  371.           && (NewDragon.PieceTable[z=(6*12*i+12*y+x)]>0) )
  372.      {
  373.        if ( x==0 || x==11 || ((NewDragon.PieceTable[z-1]<=0 || NewDragon.PieceTable[z+1]<=0)
  374.             && (i==3 || NewDragon.PieceTable[12*6+z]<=0)))
  375.        {
  376.          return z;
  377.        }
  378.        break;
  379.      }
  380.    }
  381.   return -1;
  382. }
  383.  
  384. // create a new dragon
  385.  
  386. VOID China::MakeDragon()
  387. {
  388.   int i,j,k,l,pos;
  389.   UBYTE *p1,*p2;
  390.  
  391.   PieceCount=MAXCOUNT;
  392.  
  393.   for (p1=p2=&EntryTable[0],i=MAXCOUNT/4; i!=0; i--)
  394.    {
  395.      *p1++=i; *p1++=i; *p1++=i; *p1++=i;
  396.    }
  397.   for (p1=(UBYTE *)&NewDragon.PieceTable[0],j=-1,i=MAXCOUNT; i!=0; i--)
  398.    {
  399.      do
  400.      {
  401.       j++; k=(-8)&j; l=j-k; k=k>>3;
  402.      } while (!(PosTable[k]&1<<l));
  403.      pos=Random(i); p1[j]=p2[pos]; p2[pos]=p2[i-1];
  404.    }
  405.   ShowDragon();
  406. }
  407.  
  408. // random number generator
  409.  
  410. LONG China::Random(ULONG Num)
  411. {
  412.   ULONG i,j;
  413.  
  414.   i=RandVal; j=i>>12; i^=j; j=i<<20; i^=j; RandVal=i; return (i%Num);
  415. }
  416.  
  417. // draw the dragon
  418.  
  419. VOID China::ShowDragon()
  420. {
  421.   ULONG *p1;
  422.   BYTE *p2;
  423.   short n;
  424.   int i,j,k,x,y,d;
  425.  
  426.   TwoSelected=OnePiece=0;
  427.  
  428.   for (p1=&BackGroundTab[0],i=4; i!=0; i--)
  429.    {
  430.      DrawImage(&RastPort,&Images[0],p1[0],p1[1]); p1++; p1++;
  431.    }
  432.   DrawBorder(&RastPort,&Border1[0],0,0);
  433.   for (p2=&NewDragon.PieceTable[0],d=10,i=4; i!=0; d-=3,i--)
  434.     for (y=0,j=6; j!=0; y+=30,j--)
  435.       for (x=0,k=12; k!=0; x+=25,k--)
  436.         if ((n=*p2++)>0)
  437.           DrawImage(&RastPort,&Images[n],x+d,y+d);
  438.   PrintPieces();
  439.   BltBitMapRastPort(&BitMap,0,0,WinPtr->RPort,0,0,WIDTH,HEIGHT-2,0xc0);
  440. }
  441.  
  442. // print remaining pieces
  443.  
  444. VOID China::PrintPieces()
  445. {
  446.   int i;
  447.  
  448.   for (i=3; i!=0; i--)
  449.    {
  450.      SetAPen(&RastPort,APenTab[i]);
  451.      RectFill(&RastPort,278-i,51-i,312+i,60+i);
  452.    }
  453.   sprintf((STRPTR)BlankStr,(STRPTR)PieceFmt,PieceCount);
  454.   PrintIText(&RastPort,&MoveIText,0,0);
  455. }
  456.  
  457. // select a file and open the file for read or write
  458.  
  459. BPTR China::ReqFile(LONG Type)
  460. {
  461.   struct Library *ArpBase;
  462.   struct ChinaReq *req;
  463.   APTR oldwin,*wptr;
  464.   BPTR file=0;
  465.  
  466.   wptr=&((struct Process *)FindTask(NULL))->pr_WindowPtr;
  467.   oldwin=*wptr; *wptr=WinPtr; WinPtr->Flags |= RMBTRAP;
  468.   if ((req=(struct ChinaReq *)AllocMem(sizeof(struct ChinaReq),MEMF_CLEAR)))
  469.   {
  470.     if ((ArpBase=OpenLibrary(ArpName,39L)))
  471.     {
  472.       req->FReq.fr_Hail   = (!Type ? LoadDragonStr : SaveDragonStr);
  473.       req->FReq.fr_File   = &req->FileBuf;
  474.       req->FReq.fr_Dir    = &req->DirBuf;
  475.       req->FReq.fr_Window = WinPtr;
  476.       req->FReq.fr_Flags  = 0x28; /* DoColor && NewWindFunc */
  477.       req->FReq.fr_res1   = 1; /* LongPath */
  478.       req->FReq.fr_Func   = (VOID (*)())ChangeFunc;
  479.       if (FileRequest(ArpBase,&req->FReq))
  480.       {
  481.         TackOn(ArpBase,&req->DirBuf[0],&req->FileBuf[0]);
  482.         file=ArpOpen(ArpBase,&req->DirBuf[0],MODE_OLDFILE+Type);
  483.       }
  484.       CloseLibrary(ArpBase);
  485.     }
  486.     FreeMem((APTR)req,sizeof(struct ChinaReq));
  487.   }
  488.   WinPtr->Flags &= ~RMBTRAP; *wptr=oldwin;
  489.   return file;
  490. }
  491.  
  492. VOID ChangeFunc()
  493. {
  494.   __asm __volatile ("movew #10,a0@;movew #10,a0@(2)");
  495. }
  496.  
  497. //
  498. // create an instance and play ...
  499. //
  500.  
  501. LONG Main()
  502. {
  503.   class China *CC3;
  504.  
  505.   if ((CC3=new(China)))
  506.   {
  507.     if (CC3->Init())
  508.       CC3->Game();
  509.     delete CC3;
  510.   }
  511.   return (0);
  512. }
  513.  
  514. //
  515. // end of China Challenge III - the C++ Version
  516. //
  517.